<template>
	<transition name="el-zoom-in-center">
		<div v-if="state.show" :key="Date.now()"
		     :style="`top: ${state.axis.y + 5}px;left: ${state.axis.x - 14}px;width:${props.width}px`"
		     aria-hidden="false" class="el-popper is-pure is-light el-dropdown__popper cus-contextmenu"
		     data-popper-placement="bottom" style="position: fixed;z-index: 9999">
			<ul class="el-dropdown-menu">
				<li v-for="(item, idx) in props.items" :key="idx" :class="item.disabled ? 'is-disabled' : ''"
				    class="el-dropdown-menu__item" tabindex="-1" @click="onContextmenuItem(item)">
					<icon v-if="item.icon" :name="item.icon" size="14"/>
					<span>{{ item.label }}</span>
				</li>
			</ul>
			<span :style="{ left: `${state.arrowAxis}px` }" class="el-popper__arrow"></span>
		</div>
	</transition>
</template>

<script lang="ts" setup>
import {reactive, toRaw, watch} from 'vue'
import type {ContextmenuItemClickEmitArg} from './interface'
import {useEventListener} from '@vueuse/core'
import Icon from '@/components/icon.vue'

interface Props {
	width?: number
	items: ContextmenuItemClickEmitArg[]
}

const props = withDefaults(defineProps<Props>(), {
	width: 150,
	items: () => []
})

const emits = defineEmits<{
	(e: 'contextmenuItemClick', item: ContextmenuItemClickEmitArg): void
}>()

const state = reactive<{
	show: boolean
	axis: Axis
	data?: ContextmenuItemClickEmitArg['data']
	arrowAxis: number
}>({
	show: false,
	axis: {
		x: 0,
		y: 0
	},
	data: undefined,
	arrowAxis: 10
})

const onShowContextmenu = (data: ContextmenuItemClickEmitArg['data'], axis: Axis) => {
	state.data = data
	state.axis = axis
	state.show = true
}

const onContextmenuItem = (item: ContextmenuItemClickEmitArg) => {
	if (item.disabled) {
		return
	}
	item.data = toRaw(state.data)
	emits('contextmenuItemClick', item)
}

const onHideContextmenu = () => {
	state.show = false
}

defineExpose({
	onShowContextmenu,
	onHideContextmenu
})

watch(() => state.show, value => {
	if (value) {
		useEventListener(document, 'click', onHideContextmenu)
		useEventListener(document, 'wheel', onHideContextmenu)
	} else {
		document.removeEventListener('click', onHideContextmenu)
		document.removeEventListener('wheel', onHideContextmenu)
	}
})

</script>

<style lang="scss" scoped>
.cus-contextmenu {
	z-index: 9999;
}

.el-popper,
.el-popper.is-light .el-popper__arrow::before {
	border: none;
	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.el-dropdown-menu__item {
	padding: 8px 20px;
	user-select: none;
}

.el-dropdown-menu__item .icon {
	margin-right: 5px;
}

.el-dropdown-menu__item:not(.is-disabled) {
	&:hover {
		background-color: var(--el-dropdown-menuItem-hover-fill);
		color: var(--el-dropdown-menuItem-hover-color);

		.fa {
			color: var(--el-dropdown-menuItem-hover-color) !important;
		}
	}
}
</style>
